package com.bobo.dao;

import com.bobo.db.DataSourceUtils;
import org.apache.log4j.Logger;

import java.lang.reflect.ParameterizedType;
import java.sql.*;

/**
 * Created by anting on 16/10/24.
 */
public class BaseDao<T> implements IBaseDao<T> {

    private Connection conn;

    /**
     * 获得连接对象
     *
     * @return
     */
    private Connection getConn() {

        if (conn == null) {
            try {
                conn = DataSourceUtils.getConn();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return conn;
    }


    static Logger logger = Logger.getLogger(BaseDao.class);


    private Class<?> clz;

    /**
     * 获取对象类包名
     *
     * @return
     */
    private Class<?> getClz() {
        if (clz == null) {
            clz = ((Class<?>)
                    (((ParameterizedType) (this.getClass().getGenericSuperclass())).getActualTypeArguments()[0]));
        }
        return clz;
    }


    /**
     * 获取对象名
     *
     * @return
     */
    private String getTable() {
        // getClz().isAnnotationPresent(Table.class)

        return getClz().getName().substring(getClz().getName().lastIndexOf(".") + 1);
    }


    public void close(PreparedStatement ps, ResultSet rs) {
//        if (rs != null) {
//            try {
//                rs.close();
//            } catch (SQLException e) {
//                e.printStackTrace();
//            }
//        }
//        if (ps != null) {
//            try {
//                ps.close();
//            } catch (SQLException e) {
//                e.printStackTrace();
//            }
//        }


    }

    /**
     * 不带条件查询数据记录总数
     *
     * @return
     */
    @Override
    public Integer getCount() {
        return pageNum("");
    }

    /**
     * 带条件查询数据记录总数
     *
     * @param sql sql语句
     * @param obj 查询条件
     * @return
     */
    @Override
    public Integer getCount(String sql, Object... obj) {
        return pageNum(sql, obj);
    }

    /**
     * 删除单条表中数据
     *
     * @param id id
     * @return
     */
    @Override
    public Boolean delete(Integer id) {
        String table = getTable();
        table = "t_" + table.substring(0, 1).toLowerCase() + table.substring(1);
        String sql = "DELETE FROM " + table + " WHERE id=?";

        return update(sql, id);
    }


    /**
     * 数据记录总数
     *
     * @param where
     * @param obj
     * @return
     */
    private Integer pageNum(String where, Object... obj) {
        String table = getTable();
        table = "t_" + table.substring(0, 1).toLowerCase() + table.substring(1);
        String sql = "Select count(*) from " + table + " " + where;

        return getPageCount(sql, obj);
    }

    /**
     * 查询数据记录总数
     *
     * @param sql sql
     * @param obj 条件
     * @return
     */
    private Integer getPageCount(String sql, Object... obj) {

        Integer pageNum = 0;
        Connection conn = getConn();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < obj.length; i++) {
                ps.setObject(i + 1, obj[i]);
            }
            rs = ps.executeQuery();
            while (rs.next()) {
                pageNum = rs.getInt(1);
            }

        } catch (SQLException e) {
            logger.error(e.getMessage());
        } finally {
            close(ps, rs);
        }
        return pageNum;
    }

    /**
     * 添加数据并返回主键
     *
     * @param sql
     * @param obj
     * @return
     */
    public Integer create(String sql, Object... obj) {

        Integer id = null;
        ResultSet rs = null;
        PreparedStatement ps = null;
        try {
            Connection conn = this.getConn();

            ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            for (int i = 0; i < obj.length; i++) {
                ps.setObject(i + 1, obj[i]);
            }
            ps.execute();

            rs = ps.getGeneratedKeys();
            rs.next();
            id = rs.getInt(1);

        } catch (SQLException e) {
            e.fillInStackTrace();
        } finally {
            close(ps, rs);
        }
        return id;


    }

    /**
     * 更新
     *
     * @param sql
     * @param obj
     * @return
     */
    public Boolean update(String sql, Object... obj) {
        Connection conn = getConn();
        int row = 0;
        PreparedStatement ps = null;
        try {

            ps = conn.prepareStatement(sql);
            for (int i = 0; i < obj.length; i++) {
                ps.setObject(i + 1, obj[i]);
            }
            row = ps.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {

            close(ps, null);

        }

        return row > 0;

    }

    /**
     * 获取查询结果集
     *
     * @param sql
     * @param obj
     * @return
     */
    public ResultSet getObject(String sql, Object... obj) {
        ResultSet rs = null;
        PreparedStatement ps = null;

        try {
            Connection conn = this.getConn();
            ps = conn.prepareStatement(sql);

            if (obj != null && obj.length > 0) {
                for (int i = 0; i < obj.length; i++) {
                    ps.setObject(i + 1, obj[i]);
                }
            }

            rs = ps.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close(ps, rs);
        }
        return rs;
    }

    /**
     * 获取分页列表集合
     *
     * @param sql
     * @param current  当前页数
     * @param pageSize 每页几条数据
     * @param obj      where 条件
     * @return
     */
    public ResultSet pager(String sql, Integer current, Integer pageSize, Object... obj) {

        StringBuilder sb = new StringBuilder();

        sb.append(sql);

        if (current > 0 && pageSize > 0) {
            sb.append(" limit ");
            sb.append((current - 1) * pageSize);
            sb.append(",");
            sb.append(pageSize);
        }


        return this.getObject(sb.toString(), obj);

    }


}
